package Agent;

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Vector;
import Env.*;
/**
 * TODO Put here a description of what this class does.
 *
 * @author danny.
 *         Created 18/11/2011.
 */
public class GreedyAgent extends AbstractAgent {
	
	private Vector<Integer> path;
//	private int positionInPath;
	final float[] distance ;
	
	
	public GreedyAgent (int start,int goal,Environment env) throws Exception{
		super(start,goal,env);
//		positionInPath=0;
		position = start;
		distance = new float[env.getGraph().n+1];
		path=dijkstra(start,goal,env.getGraph());
		
	}

	private Vector<Integer> dijkstra(int start, int goal, Graph graph) throws Exception {
		
		boolean [] S= new boolean [graph.n+1];
		final int[] papa = new int[graph.n+1];
		Vector<Integer> path = new Vector<Integer>();
		
		PriorityQueue<Integer> Q= new PriorityQueue<Integer>(graph.n,new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return distance[o1]-distance[o2]>0?1:distance[o1]-distance[o2]==0?0:1;
			}
		});
		
		for (int i=1;i<=graph.n;i++){
			if (i==start)
				distance[i]=0;
			else 
				distance[i]=Integer.MAX_VALUE;
			
			Q.add(i);
		}
		
		while (!Q.isEmpty()){
			int v=Q.poll();
			Vector<Integer> q= graph.getAllConnected(v);
			for (Integer i:q){
				if (!S[i]){
					float cost=graph.getEdgeCost(v,i);
					if (distance[i]>distance[v]+cost){
						distance[i]=distance[v]+cost;
						papa[i]=v;
					}
				}
			}
			S[v]=true;
		}
		if (distance[goal]==Integer.MAX_VALUE)
			return null;
		
		int current = goal;
		path.add(new Integer(goal));
		while (current!=start){
			path.add(0, new Integer(papa[current]));
			current = papa[current];
		}
		path.remove(0);
		
		return path;
	}

	@Override
	protected void chooseCarAndVertex() throws Exception {
		chosenVertex = path.elementAt(0); path.remove(0);
		if (env.getGraph().isEdgeFlooded(position, chosenVertex))
			chosenCar = env.maxEffCar(position);
		else
			chosenCar = env.maxCar(position);
	}
	
	public void move() throws Exception {
		if (this.path==null){
			stopFlag=true;
			Main.Main.log.fine("agent "+this.agentName+" No Path Found");
			return ;
		}
		super.move();
		if (path.size() == 0)
			stopFlag = true;
	}
}
